/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.base;

import java.io.IOException;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJBException;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.TypedQuery;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import org.base.util.JsfUtil;

/**
 *
 * @author mmanto
 */
@Named("expedienteBean")
@SessionScoped
public class ExpedienteBean implements Serializable {

    @Inject
    private ExpedienteController expController;

    @Inject
    private PaseController paseController;

    @Inject
    private AbstractFacade<Pase> paseEjbFacade;
    
    @Inject
    private AbstractFacade<Expediente> expedienteEjbFacade;

    @Inject
    private DepartamentoController departamentoController;

    @Inject
    private LoginFacade loginFacade;
    
    @Inject
    private LoginController loginController;

    private Login login;
    
    @Inject
    private DepartamentoController partidoController;
    
    private Expediente expedienteSelected;

    private List<Expediente> expedientes = new ArrayList<>();

    private List<Pase> pases = new ArrayList<>();

    private List<Departamento> departamentos = new ArrayList<>();

    private List<Partido> partidos = new ArrayList<>();

    private Pase paseSelected;

    private enum PersistAction {

        CREATE,
        DELETE,
        UPDATE
    }

    @PostConstruct
    public void init() {
        expedientes.addAll(expController.getItems());
    }

    public Login getLogin() {
        if (login == null) {
            login = new Login();
        }
        return login;
    }

    public void pasePrepareCreate(ActionEvent event) {
        this.login = loginController.getSelected();
        TypedQuery<Login> query = loginFacade.getEntityManager().
                createNamedQuery("Login.findByUsernameAndPassword", Login.class);
        query.setParameter("username", login.getUsername());
        query.setParameter("password", login.getPassword());
        Departamento departamento = ((Login) query.getSingleResult()).getDepartamento();

        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext context = facesContext.getExternalContext();
        facesContext.getExternalContext().getSessionMap().put("usuarioLogueadoId", login.getUserid());
        this.paseSelected = new Pase();
        this.paseSelected.setDepartamentoOrigen(departamento);
        this.paseSelected.setExpediente(getExpedienteSelected());
    }

    public void expedientePrepareCreate(ActionEvent event) {
            this.expedienteSelected = new Expediente();
    }

    public void eliminarPase(ActionEvent event) {
        pasePersist(PersistAction.DELETE, "Pase eliminado", this.paseSelected);
        actualizarPases();
    }

    public void aPases(ActionEvent event) {
        expedienteSelected = (Expediente) event.getComponent().getAttributes().get("expediente");
        actualizarPases();
        //asdf
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext ctxt = facesContext.getExternalContext();
        try {
            ctxt.redirect("/sigei/faces/pase/index.xhtml");
        } catch (IOException ex) {
            Logger.getLogger(PaseController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void expedientePersist(PersistAction persistAction, String successMessage, Expediente selected) {
        if (selected != null) {
            try {
                if (persistAction != PersistAction.DELETE) {
                    this.expedienteEjbFacade.edit(selected);
                } else {
                    this.expedienteEjbFacade.remove(selected);
                }
                JsfUtil.addSuccessMessage(successMessage);
            } catch (EJBException ex) {
                Throwable cause = JsfUtil.getRootCause(ex.getCause());
                if (cause != null) {
                    if (cause instanceof ConstraintViolationException) {
                        ConstraintViolationException excp = (ConstraintViolationException) cause;
                        for (ConstraintViolation s : excp.getConstraintViolations()) {
                            JsfUtil.addErrorMessage(s.getMessage());
                        }
                    } else {
                        String msg = cause.getLocalizedMessage();
                        if (msg.length() > 0) {
                            JsfUtil.addErrorMessage(msg);
                        } else {
                            JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                        }
                    }
                }
            } catch (Exception ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
                JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/MyBundle").getString("PersistenceErrorOccured"));
            }
        }
    }
    private void pasePersist(PersistAction persistAction, String successMessage, Pase selected) {
        if (selected != null) {
            try {
                if (persistAction != PersistAction.DELETE) {
                    this.paseEjbFacade.edit(selected);
                } else {
                    this.paseEjbFacade.remove(selected);
                }
                JsfUtil.addSuccessMessage(successMessage);
            } catch (EJBException ex) {
                Throwable cause = JsfUtil.getRootCause(ex.getCause());
                if (cause != null) {
                    if (cause instanceof ConstraintViolationException) {
                        ConstraintViolationException excp = (ConstraintViolationException) cause;
                        for (ConstraintViolation s : excp.getConstraintViolations()) {
                            JsfUtil.addErrorMessage(s.getMessage());
                        }
                    } else {
                        String msg = cause.getLocalizedMessage();
                        if (msg.length() > 0) {
                            JsfUtil.addErrorMessage(msg);
                        } else {
                            JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                        }
                    }
                }
            } catch (Exception ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
                JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/MyBundle").getString("PersistenceErrorOccured"));
            }
        }
    }

    public void savePaseNew(ActionEvent event) {
        String msg = "Pase Creado";
        pasePersist(PersistAction.CREATE, msg, getPaseSelected());
        actualizarPases();
    }

    public void expedienteSaveNew(ActionEvent event) {
        String msg = "Expediente Creado";
        expedientePersist(PersistAction.CREATE, msg, getExpedienteSelected());
        actualizarPases();
        actualizarExpedientes();
    }
    private void actualizarPases() {
        pases.clear();
        pases.addAll(paseController.pases(expedienteSelected));
    }

    public boolean isValidationFailed() {
        return JsfUtil.isValidationFailed();
    }

    public void pasePersist(ActionEvent event) {
        paseController.saveNew(event);
    }

    public Expediente getExpedienteSelected() {
        return expedienteSelected;
    }

    public void setExpedienteSelected(Expediente expedienteSelected) {
        this.expedienteSelected = expedienteSelected;
    }

    public List<Pase> getPases() {
        return pases;
    }

    public void setPases(List<Pase> pases) {
        this.pases = pases;
    }

    public List<Expediente> getExpedientes() {
        return expedientes;
    }

    public void setExpedientes(List<Expediente> expedientes) {
        this.expedientes = expedientes;
    }

    public ExpedienteController getExpController() {
        return expController;
    }

    public void setExpController(ExpedienteController expController) {
        this.expController = expController;
    }

    public Pase getPaseSelected() {
        return paseSelected;
    }

    public void setPaseSelected(Pase paseSelected) {
        this.paseSelected = paseSelected;
    }

    public void edit(ActionEvent event) {
        paseSelected = (Pase) event.getComponent().getAttributes().get("paseSelected");
    }

    public void generarRemito(){
        FacesContext contex = FacesContext.getCurrentInstance();
        generarRemito2(contex);
       
        contex.responseComplete();
    }
    
    public void generarRemito2(FacesContext contex) {
        try {
//            paseSelected = (Pase) event.getComponent().getAttributes().get("paseSelected");
            Connection con = DriverManager.getConnection("jdbc:postgresql://localhost:5432/SIG_DESA", "postgres", "postgres");
            Map parametros = new HashMap();
            parametros.put("id", this.paseSelected.getId());
            //FacesContext contex = FacesContext.getCurrentInstance();
            ServletContext servletContext = (ServletContext) contex.getExternalContext().getContext();
            HttpServletResponse response = (HttpServletResponse) contex.getExternalContext().getResponse();
            response.addHeader("content-disposition", "attachmen:filename*reporte.pdf");
            response.setContentType("application/pdf");
                       
            String path = this.obtenerPathReporte(servletContext);  
            
            JasperPrint impresion = JasperFillManager.fillReport(path, parametros, con);
            
            JasperExportManager.exportReportToPdfStream(impresion, response.getOutputStream());
//            contex.responseComplete();
            
            
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }

    }

    public String obtenerPathReporte(ServletContext servletContext) {
            String s = System.getProperty("file.separator");
            String realPath = servletContext.getRealPath(s);
            int positionTarget = realPath.lastIndexOf("target");
            String root = realPath.substring(0, positionTarget);
            String ruta = root + "src" + s + "main" + s +"reports" + s + "remitoPase2.jasper"; 
            return ruta;
    }
    
    public List<Departamento> getDepartamentos() {
        return departamentos;
    }

    public void setDepartamentos(List<Departamento> departamentos) {
        this.departamentos = departamentos;
    }

    public List<Partido> getPartidos() {
        return partidos;
    }

    public void setPartidos(List<Partido> partidos) {
        this.partidos = partidos;
    }

    public void volverAExpediente() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext ctxt = facesContext.getExternalContext();
        try {
            ctxt.redirect("/sigei/faces/faces/expediente/index.xhtml");
        } catch (IOException ex) {
            Logger.getLogger(PaseController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
     public void actualizarExpedientes(){
        expedientes.clear();
        expedientes.addAll(expedienteEjbFacade.findAll());
    }

     public void eliminarExpediente(ActionEvent event) {
        expedientePersist(PersistAction.DELETE, "Expediente eliminado", this.expedienteSelected);
        actualizarExpedientes();
    }
}
